package org.opens.javaskill.design;

public class CommandPattern {

    public static void main(String[] args) {
        // 用户1
        Receiver s1 = new Receiver("s1");
        // 用户2
        Receiver s2 = new Receiver("s2");
        // 系统
        Invoker invoker = new Invoker(null);

        // s1要执行ls命令
        Command s1Ls = new LsCommand(s1);

        // s2要执行ls, rm指令
        Command s2Ls = new LsCommand(s2);
        Command s2Rm = new RmCommand(s2);

        invoker.setCommand(s1Ls);
        invoker.call();

        invoker.setCommand(s2Ls);
        invoker.call();
        invoker.setCommand(s2Rm);
        invoker.call();
    }

}

/**
 * 说明:
 *      1. 系统中的每一个命令都需要实现这个接口.
 */
interface Command {

    public void execute();

}

/**
 * 说明:
 *      1. 相当于是系统, 命令的真正执行者.
 */
class Invoker {

    private Command command;

    public Invoker(Command command) {
        this.command = command;
    }

    public void setCommand(Command command) {
        this.command = command;
    }

    /**
     * 功能:
     *      执行设置的Command的execute方法.
     */
    public void call() {
        this.command.execute();
    }

}

/**
 * 功能:
 *      向系统发送命令的用户.
 */
class Receiver {

    private String name;

    public Receiver(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    /**
     * 说明:
     *      1. 该方法负责将指令的执行结果返回给用户.
     */
    public void action() {
        System.out.println(name + " 接受到命令返回值");
    }

}

/**
 * 说明:
 *      1. 这是ls命令.
 */
class LsCommand implements Command {

    /**
     * 说明:
     *      1. 指令持有这个对象是因为指令执行需要有返回值, 待指令执行完毕之后还需要将指令的返回值返回给用户.
     */
    private Receiver receiver;

    public LsCommand(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        System.out.println(receiver.getName() + " 执行ls命令-开始");
        receiver.action();
        System.out.println(receiver.getName() + " 执行ls命令-结束");
    }

}

/**
 * 说明:
 *      1. 这是rm命令.
 */
class RmCommand implements Command {

    private Receiver receiver;

    public RmCommand(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public void execute() {
        System.out.println(receiver.getName() + " 执行rm命令-开始");
        receiver.action();
        System.out.println(receiver.getName() + " 执行rm命令-结束");
    }

}